package classification;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import tools.FrenchTokenizer;
import tools.Normalizer;

public class Classification {

	private String corpusPath;
	private ArrayList<String> dictionary;
	
	// mod�le binomial (Bernoulli)
	private HashMap<String, Integer> nbDocHam;
	private HashMap<String, Integer> nbDocSpam;
	private int nbDocumentsHam;
	private int nbDocumentsSpam;
	private int nbDocumentsTotal;
	
	// mod�le multinomial
	private HashMap<String, Integer> nbOccHam;
	private HashMap<String, Integer> nbOccSpam;
	private int nbMotsHam; // nombre total de mots dans la cat�gorie Ham
	private int nbMotsSpam; // nombre total de mots dans la cat�gorie Spam
	private HashMap<String, Double> frequencyHam;
	private HashMap<String, Double> frequencySpam;
	
	
	public Classification(String corpusPath)
	{
		this.corpusPath = corpusPath;
		dictionary = new ArrayList<String>();
		Normalizer normalizer = new FrenchTokenizer();
		
		nbDocHam = new HashMap<String, Integer>();
		nbDocSpam = new HashMap<String, Integer>();
		nbDocumentsTotal = 0;
		nbDocumentsHam = 0;
		nbDocumentsSpam = 0;
		
		nbOccHam = new HashMap<String, Integer>();
		nbOccSpam = new HashMap<String, Integer>();
		nbMotsHam = 0;
		nbMotsSpam = 0;
		frequencyHam = new HashMap<String, Double>();
		frequencySpam = new HashMap<String, Double>();

		createTable(normalizer);
		calculerFrequency();
	}
	
	public void createTable(Normalizer normalizer)
	{
		String corpusUtilisePath = corpusPath;
		File dossierPrincipal = new File(corpusUtilisePath);
		
		String dossierSecondairePath, dossierTertiairePath, dossierPath,fichierPath;
		File dossierSecondaire, dossierTertiaire, dossier, fichier;
		
		//lingspam
		if(dossierPrincipal.isDirectory())
		{
			//bare
			for(String nomDossierSecondaire : dossierPrincipal.list())
			{
				dossierSecondairePath = corpusUtilisePath + File.separator + nomDossierSecondaire;
				dossierSecondaire = new File(dossierSecondairePath);
				//part
				if(dossierSecondaire.isDirectory())
				{
					for(String nomDossierTertiaire : dossierSecondaire.list())
					{
						dossierTertiairePath = dossierSecondairePath + File.separator + nomDossierTertiaire;
						dossierTertiaire = new File(dossierTertiairePath);
						if(dossierTertiaire.isDirectory())
						{
							for(String nomDossier : dossierTertiaire.list())
							{
								dossierPath = dossierTertiairePath + File.separator + nomDossier;
								dossier = new File(dossierPath);
								if(dossier.isDirectory())
								{
									for(String fileName : dossier.list())
									{
										fichierPath = dossierPath + File.separator + fileName;
										fichier = new File(fichierPath);
										
										if(fichier.isFile())
										{
											this.nbDocumentsTotal ++;
											if(fichier.getName().contains("spm"))
											{
												this.nbDocumentsSpam++;
												ajouterWords(fichierPath, normalizer,true);
											}
											else
											{
												this.nbDocumentsHam++;
												ajouterWords(fichierPath, normalizer,false);
											}
											
										}
										else
										{
											System.err.println(fichierPath + " : fichier attendu");
										}
									}
								}
								else
								{
									System.err.println(dossierPath + " : dossier attendu");
								}
							}	
						}
						else
						{
							System.err.println(dossierTertiairePath + " : dossier attendu");
						}
					}
				}
				else
				{
					System.err.println(dossierSecondairePath + " : dossier attendu");
				}
			}
		}
		else
		{
			System.err.println("dossier " + dossierPrincipal + " non trouver dans le corpus");
		}
	}
	
	public void ajouterWords(String fichier, Normalizer normalizer, boolean spam)
	{
		ArrayList<String> words;
		boolean flag1 = false;
		boolean flag2 = false;
		try {
			words = normalizer.normalize(fichier);
			for (String word : words) {
				if(!dictionary.contains(word))
					dictionary.add(word);
				if(spam && !flag1)
				{
					if(nbDocSpam.containsKey(word))
					{
						int num = nbDocSpam.get(word);
						nbDocSpam.put(word, num+1);
					}
					else
						nbDocSpam.put(word, 1);
					
					flag1 = true;
				}
				else if(!spam && !flag2)
				{
					if(nbDocHam.containsKey(word))
					{
						int num = nbDocHam.get(word);
						nbDocHam.put(word, num+1);
					}
					else
						nbDocHam.put(word, 1);
					
					flag2 = true;
				}
				
				if(spam)
				{
					if(nbOccSpam.containsKey(word))
					{
						int num = nbOccSpam.get(word);
						nbOccSpam.put(word, num+1);
					}
					else
						nbOccSpam.put(word, 1);
					this.nbMotsSpam++;
				}
				else
				{
					if(nbOccHam.containsKey(word))
					{
						int num = nbOccHam.get(word);
						nbOccHam.put(word, num+1);
					}
					else
						nbOccHam.put(word, 1);
					this.nbMotsHam++;
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	public void calculerFrequency()
	{
		for (Map.Entry<String, Integer> hit : this.nbOccSpam.entrySet()) {
			String mot = hit.getKey();
			int occu = hit.getValue();
			double freq = occu*1.0/this.nbMotsSpam;
			this.frequencySpam.put(mot, freq);
		}
		
		for (Map.Entry<String, Integer> hit : this.nbOccHam.entrySet()) {
			String mot = hit.getKey();
			int occu = hit.getValue();
			double freq = occu*1.0/this.nbMotsHam;
			this.frequencyHam.put(mot, freq);
		}
	}
	
	public static void main(String[] args)
	{
		Classification c= new Classification("D:/EEworkspace/ProjetEIT/lingspam");
	}
}
